/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using System.Xml;
using System.Xml.Schema;

namespace System.Qizx.Api {

    /// <summary> Nodes of the Document Data Model, as defined by XQuery1/XPath2, plus
    /// extensions.
    /// <para>
    /// <b>Caution</b>: a node of a Data Model can be represented by several
    /// different instances of Node. Therefore Node instances should never be
    /// compared with <code>==</code>, but with the <code>equals</code>
    /// method, or possibly with the documentOrderCompareTo method.</para>
    /// <para>
    /// <b><a id="cex">Common exception causes</a></b>: the node belongs to an
    /// unreachable Document (deleted or belonging to a closed Library).</para>
    /// </summary>
    public enum XdmNodeType {
        Unknown = -1,
        None = 0,
        /// <summary>Node nature (returned by getNodeNature) for a document node. </summary>
        Document = 1,
        /// <summary>Node nature (returned by getNodeNature) for an Element node. </summary>
        Element = 2,
        /// <summary>Node nature (returned by getNodeNature) for an Attribute node. </summary>
        Attribute = 3,
        /// <summary>Node nature (returned by getNodeNature) for a naemespacenode. </summary>
        Namespace = 4,
        /// <summary> Node nature (returned by getNodeNature) for a processing instruction
        /// node.
        /// </summary>
        ProcessingInstruction = 5,
        /// <summary>Node nature (returned by getNodeNature) for a Comment node. </summary>
        Comment = 6,
        /// <summary>Node nature (returned by getNodeNature) for a leaf text node. </summary>
        Text = 7,
        /// <summary> Node nature (returned by getNodeNature) for a typed leaf node holding a
        /// boolean value.
        /// </summary>
        AtomBoolean = 8,
        /// <summary> Node nature (returned by getNodeNature) for a typed integer node,
        /// holding a long integer value.
        /// </summary>
        AtomLong = 9,
        /// <summary> Node nature (returned by getNodeNature) for a typed leaf node holding a
        /// double value.
        /// </summary>
        AtomDouble = 10,
        /// <summary> Node nature (returned by getNodeNature) for typed leaf node holding a
        /// value of any serializable class.
        /// </summary>
        AtomAny = 11,
        /// <summary> Node nature (returned by getNodeNature) for typed leaf node holding a
        /// date/time value.
        /// </summary>
        AtomDate = 12
    }

    /// <summary>
    /// 
    /// </summary>
    public interface Node : Item {
        /// <summary> Returns the node kind as a string: "document", "element", "attribute",
        /// "text", "comment", or "processing-instruction".
        /// <para>Corresponds to Data Model accessor dm:node-kind().</para>
        /// </summary>
        /// <returns> a String representing the node kind.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        string NodeKind {
            get;

        }
        /// <summary> Returns the Qualified Name of the node.
        /// <p>
        /// Corresponds to Data Model accessor dm:node-name().</p>
        /// </summary>
        /// <returns> the name of the node (for element and attribute), the target for
        /// a processing-instruction, null if the node has no name
        /// (document, text, comment).
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        QName NodeName {
            get;

        }

        /// <summary>
        /// When overridden in a derived class, gets the local name of the node.
        /// </summary>
        /// <value>The name of the local.</value>
        string LocalName { get; }

        /// <summary>
        /// When overridden in a derived class, gets the qualified name of the node.
        /// </summary>
        /// <value>The name.</value>
        string Name { get; }

        /// <summary>
        /// Gets the namespace URI of this node.
        /// </summary>
        /// <value>The namespace URI.</value>
        string NamespaceURI { get; }

        /// <summary> Returns the first child node of an element or a document node.</summary>
        /// <returns> null if the node has no first child.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        Node FirstChild {
            get;
        }

        /// <summary>
        /// Gets the last child of the node. 
        /// </summary>
        /// <value>The last child.</value>
        Node LastChild { get; }

        /// <summary>
        /// Gets a value indicating whether this node has any child nodes. 
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has child nodes; otherwise, <c>false</c>.
        /// </value>
        bool HasChildNodes { get; }

        /// <summary>
        /// Gets or sets the concatenated values of the node and all its child nodes.
        /// </summary>
        /// <value>The inner text.</value>
        string InnerText { get; set; }

        /// <summary>
        /// Gets or sets the markup representing only the child nodes of this node.
        /// </summary>
        /// <value>The inner XML.</value>
        string InnerXml { get; set; }

        /// <summary>
        /// Gets the markup representing this node and all its child nodes.
        /// </summary>
        /// <value>The outer XML.</value>
        string OuterXml { get; }

        /// <summary>
        /// Returns the next Node in document order. If this node has children,
        /// the next node is the first child; otherwise this is the first of the
        /// following nodes (in the sense of the XPath axis 'following').
        /// </summary>
        /// <value>The next node.</value>
        /// <returns> the next node, or null if the node has no successor.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        Node NextNode {
            get;
        }

        /// <summary>
        /// Gets the node immediately preceding this node.
        /// </summary>
        /// <value>The previous sibling.</value>
        Node PreviousSibling { get; }

        /// <summary>
        /// Gets or sets the namespace prefix of this node
        /// </summary>
        /// <value>The prefix.</value>
        string Prefix { get; set; }

        /// <summary>
        /// Returns the String Value of this Node.
        /// <para>
        /// Corresponds to the XQuery Data Model accessor dm:string-value().
        /// </para>
        /// </summary>
        /// <value>The string value.</value>
        /// <returns> the string value of the node. For an element, it is the
        /// concatenation of text nodes contained in the element.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        string StringValue {
            get;
        }

        /// <summary>
        /// Gets the post schema validation infoset that has been assigned to this node as a result of schema validation.
        /// </summary>
        /// <value>The schema info.</value>
        IXdmSchemaInfo SchemaInfo { get; }

        XmlSchemaSet Schemas { get; }


        /// <summary>
        /// Returns the String Value of this leaf Node as a char array.
        /// <para>
        /// Corresponds to the XQuery Data Model accessor dm:string-value().
        /// </para>
        /// </summary>
        /// <value>The char value.</value>
        /// <returns> the string value of the node.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>, Node is not </throws>
        char[] CharValue {
            get;
        }

        /// <summary>
        /// Return the base-URI of this Node.
        /// <para>
        /// Corresponds to the XQuery Data Model accessor dm:base-uri().</para>
        /// </summary>
        /// <value>The base URI.</value>
        /// <returns> the base-URI as a String
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        string BaseURI {
            get;
        }

        /// <summary>
        /// Returns the URI of the document.
        /// </summary>
        /// <value>The document URI.</value>
        /// <returns> the document URI as a String
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        string DocumentURI {
            get;

        }
        /// <summary> Returns the document node if any, else the top-level node.</summary>
        /// <returns> the topmost ancestor node.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        Node OwnerDocument {
            get;

        }
        /// <summary> Returns a node kind in numeric form: DOCUMENT, ELEMENT etc.</summary>
        /// <returns> an integer representing the node nature
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        XdmNodeType NodeType {
            get;

        }
        /// <summary> Returns the number of attributes of an Element. Returns 0 if the node is
        /// not an Element.
        /// </summary>
        /// <returns> an integer which is the number of attributes
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        int AttributeCount {
            get;
        }


        /// <summary>
        /// Returns the parent node.
        /// Corresponds to the XQuery Data Model accessor dm:parent().
        /// </summary>
        /// <returns>
        /// the parent node or null if the node has no parent.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        Node ParentNode { get; }

        /// <summary> Returns the next sibling Node.</summary>
        /// <returns> null if the node has no next sibling.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        Node NextSibling { get; }

        // --------------------------------------------------------------
        // Extended accessors
        // --------------------------------------------------------------

        /// <summary>
        /// Returns true if the Node is an Element. Convenience method equivalent
        /// to: <code>getNodeNature() == Node.ELEMENT</code>.
        /// </summary>
        /// <returns>true if this node is an XML element</returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        bool IsElement { get; }

        /// <summary>
        /// Gets a value indicating whether this instance is read only.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is read only; otherwise, <c>false</c>.
        /// </value>
        bool IsReadOnly { get; }

        //Node Item[string name] { get; }

        /// <summary> Gets an attribute of an element by name.</summary>
        /// <param name="name">qualified name of the sought attribute
        /// </param>
        /// <returns> An attribute node; null if not found or not applied to an
        /// element.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        Node GetAttributeNode(System.Xml.XmlQualifiedName name);

        /// <summary> Gets the attributes of an element.</summary>
        /// <returns> an array of attribute nodes, or null if the node has no
        /// attributes.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        Node[] Attributes { get; }

        // ----- Extensions for typed atomic values ------------------------------

        /// <summary>
        /// Returns a matching prefix for the Namespace URI by looking up the
        /// in-scope namespace definitions.
        /// </summary>
        /// <param name="nsURI">a namespace URI as a String</param>
        /// <returns>
        /// the first suitable prefix, otherwise null if none is found.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        string GetPrefixOfNamespace(string nsURI);

        /// <summary>
        /// Returns a matching Namespace for the prefix by looking up the in-scope
        /// namespace definitions.
        /// </summary>
        /// <param name="prefix">a prefix as a String (canbe the empty string)</param>
        /// <returns>
        /// the first suitable namespace URI, otherwise null if none is
        /// found.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        string GetNamespaceOfPrefix(string prefix);

        /// <summary>
        /// Compares the document order of two nodes.
        /// </summary>
        /// <param name="that">other node to compare</param>
        /// <returns>
        /// -1 if this node is strictly before that node in document order,
        /// 0 if nodes are identical, 1 if after that node. If the two nodes belong
        /// to different documents, returns an arbitrary but stable "order of
        /// documents".
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        int DocumentOrderCompareTo(Node that);

        /// <summary>
        /// Compares the string values of two nodes, optionally using a collation.
        /// </summary>
        /// <param name="node">other node to compare</param>
        /// <param name="collator">an optional collator to compare string values; can be null</param>
        /// <returns>
        /// 0 if string values are equal, a negative integer if this string
        /// value is before the string value of the other node, a positive value
        /// otherwise.
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        int StringValueCompareTo(Node node, System.Globalization.CompareInfo collator);

        /// <summary> Deep equality of two subtrees. Implements fn:deep-equal on Node.</summary>
        /// <param name="node">other node to compare
        /// </param>
        /// <param name="collator">an optional collator to compare string values; can be null
        /// </param>
        /// <returns> true if the two nodes are deeply equal
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a> </throws>
        bool DeepEquals(Node node, System.Globalization.CompareInfo collator);

        /// <summary>
        /// Returns true if this node is an ancestor of the parameter node or the
        /// node itself.
        /// </summary>
        /// <param name="node">other node to check for containment</param>
        /// <returns>
        /// true if the node argument is a descendant
        /// </returns>
        /// <throws>  DataModelException <a href="#cex">common causes</a>
        /// </throws>
        bool Contains(Node node);

        //coshare extended
        ItemSequence SelectItems(string xpath);
        Item SelectSingleItem(string xpath);
        Item SelectSingleItem(string xpath, IXmlNamespaceResolver resolver);
        ItemSequence SelectItems(string xpath, IXmlNamespaceResolver resolver);

    }
}